﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Text;

namespace Vici.CoolStorage
{
    public abstract partial class CSObject<TObject, TKey> : CSObject<TObject>
    {
        #region 分页方法
        /// <summary>
        /// 分页方法
        /// </summary>
        /// <param name="orderBy">排序字段</param>
        /// <returns></returns>
        public static CSList<TObject> PageList(string orderBy)
        {
            return PageList(orderBy, new CSFilter());
        }
        /// <summary>
        /// 分页方法
        /// </summary>
        /// <param name="orderBy">排序字段</param>
        /// <param name="condition">数据条件</param>
        /// <param name="fields">字段名称</param>
        /// <returns></returns>
        public static CSList<TObject> PageList(string orderBy, CSFilter condition, params string[] fields)
        {
            string pageSize = System.Web.HttpContext.Current.Request.Form["rows"];
            string pageIndex = System.Web.HttpContext.Current.Request.Form["page"];
            if (string.IsNullOrEmpty(pageSize)) pageSize = "10";
            if (string.IsNullOrEmpty(pageIndex)) pageIndex = "1";
            return PageList(string.Empty, orderBy, condition, int.Parse(pageSize), int.Parse(pageIndex), fields);
        }
        /// <summary>
        /// 分页方法
        /// </summary>
        /// <param name="orderBy">排序字段</param>
        /// <param name="pageSize">数量</param>
        /// <param name="pageIndex">当前页</param>
        /// <returns></returns>
        public static CSList<TObject> PageList(string orderBy, int pageSize, int pageIndex)
        {
            return PageList(orderBy, new CSFilter(), pageSize, pageIndex);
        }
        public static CSList<TObject> PageList(string orderBy, CSFilter sqlWhere, int pageSize, int pageIndex, params string[] fields)
        {
            return PageList(string.Empty, orderBy, sqlWhere, pageSize, pageIndex, fields);
        }
        public static CSList<TObject> PageList(string tableName, string orderBy, CSFilter sqlWhere, int pageSize, int pageIndex, params string[] fields)
        {
            CSList<TObject> records = new CSList<TObject>(sqlWhere).OrderedBy(orderBy);
            int totalPages = Convert.ToInt32(Math.Round(Convert.ToDecimal(records.CountFast) / Convert.ToDecimal(pageSize)));
            int totalRecords = records.CountFast;
            int range = pageSize * pageIndex + 1 - pageSize;
            records = records.Range(range, pageSize);
            records.TotalRecords = totalRecords;
            records.TotalPages = totalPages;
            return records;
            // CSParameterCollection paras = new CSParameterCollection();
            // paras.Add("@TableName", tableName);
            // paras.Add("@Fields", fields.Length>0?string.Join(",",fields):"*");
            // paras.Add("@OrderField", orderFields);
            // paras.Add("@sqlWhere", sqlWhere);
            // paras.Add("@pageSize", pageSize);
            // paras.Add("@pageIndex", pageIndex);
            //CSParameter param = new CSParameter("@TotalPage");
            //param.Direction = "Output";
            // paras.Add(param);
            //param = new CSParameter("@RETURN_VALUE");
            //param.Direction = "ReturnValue";
            //paras.Add(param);
            //return CSDatabase.RunQuery<T>("!up_Page", paras);
        }
        /// <summary>
        /// 获取分页HTML
        /// </summary>
        /// <param name="url">当前Url</param>
        /// <param name="page">当前页</param>
        /// <param name="pageCount">总页数</param>
        /// <returns></returns>
        public static string GetPage(string url, int page, int pageCount)
        {
            int preIndex = page > 1 ? page - 1 : 1;
            int nextIndex = pageCount > page ? page + 1 : pageCount;
            StringBuilder pageStr = new StringBuilder();
            int startIndex = 1;
            if (page > 2)
            {
                startIndex = page > pageCount - 2 ? pageCount - 4 : page - 2;
                if (page >= 4)
                {
                    pageStr.AppendFormat("<a href='/{0}/page/1'><span>1</span></a>", url);
                    if (page >= 5) pageStr.Append("<span>...</span>");
                }
            }
            int count = 0;
            for (int i = startIndex; i <= pageCount; i++)
            {
                count++;
                if (count > 5) break;
                pageStr.AppendFormat("<a href='/{0}/page/{1}'><span{2}>{1}</span></a>", url, i, i == page ? " class='this'" : "");
                if (page > 4 && i == 1) pageStr.Append("<span>...</span>");
            }
            if (pageCount > 5 && page < pageCount - 2)
            {
                if (page + 3 < pageCount) pageStr.Append("<span>...</span>");
                pageStr.AppendFormat("<a href='/{0}/page/{1}'><span>{1}</span></a>", url, pageCount);
            }

            return string.Format("<a href='/{3}/page/{0}'><span>上一页</span></a>{2}<a href='/{3}/page/{1}'><span>下一页</span></a>",
                preIndex, nextIndex, pageStr, url); ;
        }
        #endregion

        #region 生产分页数据

        public static string paging()
        {
            
            return "<div id='pageNav'></div>";
        }

        #endregion


        #region 生成分页
        /// <summary>
        /// 生成Ajax分页数据
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="dataList">内容</param>
        /// <param name="showIndex">是否显示编号</param>
        /// <returns></returns>
        public static string CreatePage(System.Collections.Generic.List<string> dataList, int totalRecords, bool showIndex = false, string footer = "")
        {
            System.Text.StringBuilder dataHTML = new System.Text.StringBuilder();
            dataHTML.AppendFormat("totalRecord = {0};", totalRecords);
            dataHTML.Append("dataStore = [");
            foreach (string data in dataList)
            {
                dataHTML.AppendFormat("\"{0}\",", data);
            }
            if (dataList.Count > 0)
                dataHTML.Remove(dataHTML.Length - 1, 1);
            dataHTML.Append("];");
            return dataHTML.ToString();
        }
        /// <summary>
        /// 生成排序数据
        /// </summary>
        /// <param name="fields">字段</param>
        /// <returns></returns>
        public static string EasySortPage(params string[] fields)
        {
            String sort = System.Web.HttpContext.Current.Request.Form["sort"];
            String order = System.Web.HttpContext.Current.Request.Form["order"];
            sort = order == "asc" ? sort = sort + "-" : sort;
            if (sort == null) sort = System.Web.HttpContext.Current.Request.Form[0];
            return EasyPage(new CSFilter(), sort, false, false, fields);
        }
        /// <summary>
        /// 生产EasyUI JSON数据
        /// </summary>
        /// <param name="byOrder">排序字段</param>
        /// <param name="isTree">是否树形表格</param>
        /// <param name="isOpen">是否打开树</param>
        /// <param name="fields">生成字段</param>
        /// <returns></returns>
        public static string EasyPage(string byOrder, bool isTree = false, bool isOpen = false, params string[] fields)
        {
            return EasyPage(new CSFilter(), byOrder, isTree, isOpen, fields);
        }

        public static string EasyPage(CSFilter filter, string byOrder, bool isTree, bool isOpen = false, params string[] fields)
        {
            if (filter == null) filter = new CSFilter();
            CSList<TObject> dataList = PageList(byOrder, filter);
            return EasyPage(dataList, dataList.TotalRecords, isTree, isOpen, fields);
        }
        /// <summary>
        /// 生成Ajax分页数据
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="dataList">内容</param>
        /// <returns></returns>
        public static string EasyPage(CSList<TObject> dataList, int totalRecords, bool isTree = false, bool isOpen = false, params string[] fields)
        {
            System.Text.StringBuilder dataHTML = new System.Text.StringBuilder();
            dataHTML.AppendFormat("{{\"total\":{0},\"rows\":[", totalRecords);
            foreach (TObject data in dataList)
            {
                dataHTML.Append("{");
                PropertyInfo[] pInfos = data.GetType().GetProperties();
                foreach (string fieldName in fields)
                {
                    List<PropertyInfo> result = pInfos.Where(a => a.Name == fieldName).ToList();
                    if (result.Count > 0)
                    {
                        string value = string.Format("{0}", result[0].GetValue(data, null));
                        if (string.IsNullOrEmpty(value)) value = "";
                        dataHTML.AppendFormat("\"{0}\":\"{1}\",", fieldName, value.Replace("\\", "\\\\"));
                    }
                }
                if (isTree)
                {
                    PropertyInfo[] paerntID = pInfos.Where(a => a.Name == "FID").ToArray();
                    if (paerntID.Length > 0)
                    {
                        string value = string.Format("{0}", paerntID[0].GetValue(data, null));
                        if (value == "0" && isOpen == false)
                        {
                            dataHTML.AppendFormat("\"{0}\":\"{1}\",", "state", "closed");
                        }
                        else
                        {
                            dataHTML.AppendFormat("\"_parentId\":{0},", value);
                        }
                        dataHTML.Remove(dataHTML.Length - 1, 1);
                    }
                }
                else
                {
                    dataHTML.Remove(dataHTML.Length - 1, 1);
                }
                dataHTML.Append("},");
            }
            if (dataList.Count > 0)
                dataHTML.Remove(dataHTML.Length - 1, 1);
            dataHTML.Append("]}");
            return dataHTML.ToString();
        }
        public static string Tree<T>(List<T> dataList, List<string> values = null, params string[] fields)
        {
            return Tree<T>(dataList, values, true, fields);
        }
        public static string Tree<T>(List<T> dataList, List<string> values = null, bool selectAll = true, params string[] fields)
        {
            if (fields.Length == 0) fields = new string[] { "id", "text" };
            System.Text.StringBuilder dataHTML = new System.Text.StringBuilder();
            if (selectAll)
            {
                dataHTML.Append("[{\"id\":\"\",\"text\":\"全选/反选\",\"children\":[");
            }
            else
            {
                dataHTML.Append("[");
            }
            string preID = string.Empty;
            foreach (T data in dataList)
            {
                dataHTML.Append("{");
                PropertyInfo[] pInfos = data.GetType().GetProperties();
                string id = string.Empty;
                foreach (string fieldName in fields)
                {
                    List<PropertyInfo> result = pInfos.Where(a => a.Name == fieldName).ToList();
                    if (result.Count > 0)
                    {
                        string value = string.Format("{0}", result[0].GetValue(data, null));
                        if (fieldName == fields[0]) id = value;
                        if (string.IsNullOrEmpty(value)) value = "&nbsp;";
                        dataHTML.AppendFormat("\"{0}\":\"{1}\",", fieldName.ToLower() == "id" ? "id" : "text", value.Replace("\\", "\\\\"));
                    }
                }
                if (values != null)
                {
                    if (values.Where(a => a == id).Count() > 0)
                        dataHTML.AppendFormat("\"{0}\":{1},", "checked", "true");
                }
                PropertyInfo[] parentID = pInfos.Where(a => a.Name == "ParentID").ToArray();
                if (parentID.Length > 0)
                {
                    string value = string.Format("{0}", parentID[0].GetValue(data, null));
                    if (value == "0")
                    {
                        dataHTML.AppendFormat("\"{0}\":\"{1}\",", "state", "closed");
                    }
                    else
                    {
                        dataHTML.AppendFormat("\"_parentId\":\"{0}\",", value);
                    }
                    dataHTML.Remove(dataHTML.Length - 1, 1);
                }
                else
                {
                    dataHTML.Remove(dataHTML.Length - 1, 1);
                }

                dataHTML.Append("},");
            }
            if (dataList.Count > 0)
                dataHTML.Remove(dataHTML.Length - 1, 1);
            if (selectAll)
            {
                dataHTML.Append("]}]");
            }
            else
            {
                dataHTML.Append("]");
            }
            return dataHTML.ToString();
        }
        #endregion

        #region 数据源绑定
        /// <summary>
        /// 数据绑定,Tree格式
        /// </summary>
        /// <param name="fields">字段</param>
        /// <returns></returns>
        public static string EasyDataBind(string checkID, params string[] fields)
        {
            CSList<TObject> dataList = List();
            System.Text.StringBuilder dataHTML = new System.Text.StringBuilder();
            dataHTML.Append("[{\"id\":\"\",\"text\":\"全选/反选\",\"children\":");
            dataHTML.Append("[");
            foreach (TObject data in dataList)
            {
                dataHTML.Append("{");
                PropertyInfo[] pInfos = data.GetType().GetProperties();
                foreach (string fieldName in fields)
                {
                    List<PropertyInfo> result = pInfos.Where(a => a.Name == fieldName).ToList();
                    if (result.Count > 0)
                    {
                        string value = string.Format("{0}", result[0].GetValue(data, null));
                        if (string.IsNullOrEmpty(value)) value = "&nbsp;";
                        if (fieldName == "ID")
                        {
                            if (checkID == value)
                            {
                                dataHTML.AppendFormat("\"id\":\"{0}\",\"checked\":true,", value);
                            }
                            else
                            {
                                dataHTML.AppendFormat("\"id\":\"{0}\",", value);
                            }
                        }
                        else
                        {
                            dataHTML.AppendFormat("\"text\":\"{0}\",", value);
                        }

                    }
                }
                dataHTML.Remove(dataHTML.Length - 1, 1);
                dataHTML.Append("},");
            }
            dataHTML.Remove(dataHTML.Length - 1, 1);
            dataHTML.Append("]}]");
            return dataHTML.ToString();
        }
        #endregion

        #region EasyUI GridTableSave
        /// <summary>
        /// 根据表单自动保存对象
        /// </summary>
        /// <param name="id">新增参数为零</param>
        /// <returns></returns>
        public static bool GridSave(TKey id)
        {
            TObject obj;
            if (System.Web.HttpContext.Current.Request.Form["isNewRecord"] != null)
            {
                obj = New();
            }
            else
            {
                obj = ReadSafe(id);
            }
            PropertyInfo[] pList = typeof(TObject).GetProperties();
            foreach (string name in System.Web.HttpContext.Current.Request.Form.AllKeys)
            {
                List<PropertyInfo> pInfo = pList.Where(a => a.Name == name && a.Name != "ID").ToList();
                if (pInfo.Count > 0)
                {
                    switch (pInfo[0].PropertyType.FullName)
                    {
                        case "System.DateTime":
                            {
                                string date = System.Web.HttpContext.Current.Request.Form[name].ToString();
                                DateTime time = Convert.ToDateTime(string.IsNullOrEmpty(date) ? null : date);
                                time = time == DateTime.MinValue ? DateTime.Now : time;
                                pInfo[0].SetValue(obj, time, null);
                            } break;

                        case "System.Int32":
                            {
                                pInfo[0].SetValue(obj, Convert.ToInt32(System.Web.HttpContext.Current.Request.Form[name]), null);
                            } break;
                        case "System.String":
                            {
                                string attribute = System.Web.HttpContext.Current.Request.Form[name].ToString();
                                if (name == "CreateUser")
                                {

                                    attribute = string.IsNullOrEmpty(attribute) ? System.Web.HttpContext.Current.Session["UserName"].ToString() : attribute; ;
                                }
                                pInfo[0].SetValue(obj, attribute, null);
                            }break;
                        default:
                            {
                                pInfo[0].SetValue(obj, System.Web.HttpContext.Current.Request.Form[name], null);
                            } break;
                    }
                }
            }

            return obj.Save();
        }
        #endregion

        #region 获取ID最大值
        /// <summary>
        /// 根据字段名称获取最大值
        /// </summary>
        /// <param name="fieldName">字段名称</param>
        /// <returns></returns>
        public static int Max(string fieldName = "ID")
        {
            return GetScalar<int>(fieldName, CSAggregate.Max);
        }
        #endregion

    }
}
